package com.itheima.d7_thread_communication;

/**
 * 目标：了解一下线程通信。
 *      黑马视频第179集
 *
 * 什么是线程通信？
 * 当多个线程共同操作共享的资源时，线程间通过某种方式互相告知自己的状态，以相互协调，并避免无效的资源争夺。
 *
 * 线程通信的常见模型（生产者与消费者模型）
 * 生产者线程负责生产数据
 * 消费者线程负责消费生产者生产的数据。
 * 注意：生产者生产完数据应该等待自己，通知消费者消费；消费者消费完数据也应该等待自己，再通知生产者生产！
 *
 * Object类的等待和唤醒方法：
 *  void wait()         让当前线程等待并释放所占锁，直到另一个线程调用notify()方法或 notifyAll()方法
 *  void notify()       唤醒正在等待的单个线程
 *  void notifyAll()    唤醒正在等待的所有线程
 *  注意
 * 上述方法应该使用当前同步锁对象进行调用。一定要拿锁对象调用wait这些方法，因为只有锁对象才知道哪个线程被占据，谁需要等待
 *
 *磊哥说了解即可
 */
public class ThreadTest {
    public static void main(String[] args) {
        //   需求：3个生产者线程，负责生产包子，每个线程每次只能生产1个包子放在桌子上
        //      2个消费者线程负责吃包子，每人每次只能从桌子上拿1个包子吃。
        Desk desk  = new Desk();
        /*
        public Thread(Runnable target, String name )
        可以创建Runnable的匿名内部类对象。
        再交给Thread线程对象。
        再调用线程对象的start()启动线程。
         */
        // 创建3个生产者线程（3个厨师）
        new Thread(() -> {
            while (true) {
                desk.put();
            }
        }, "厨师1").start();

        new Thread(() -> {
            while (true) {
                desk.put();
            }
        }, "厨师2").start();

        new Thread(() -> {
            while (true) {
                desk.put();
            }
        }, "厨师3").start();

        // 创建2个消费者线程（2个吃货）
        new Thread(() -> {
            while (true) {
                desk.get();
            }
        }, "吃货1").start();

        new Thread(() -> {
            while (true) {
                desk.get();
            }
        }, "吃货2").start();
    }
}
